"""
适配器能力声明系统

本模块定义了数据源适配器的能力声明系统，用于描述适配器的功能、性能特征等。
通过统一的能力声明，路由系统可以智能地选择最合适的数据源。

能力分类：
1. 数据能力 (DataCapability): 适配器能提供哪些类型的数据
2. 市场能力 (MarketCapability): 适配器支持哪些市场
3. 性能等级 (PerformanceLevel): 响应速度、数据新鲜度等

作者: 架构组
创建日期: 2025-10-06
"""

from enum import Enum
from typing import Set, List, Dict, Any, Optional
from dataclasses import dataclass, field
from datetime import datetime


# ==================== 数据能力枚举 ====================

class DataCapability(str, Enum):
    """
    数据能力枚举
    
    定义适配器可以提供的数据类型。
    """
    
    # 行情数据
    REALTIME_QUOTES = "realtime_quotes"           # 实时行情
    DELAYED_QUOTES = "delayed_quotes"             # 延时行情
    HISTORICAL_KLINE = "historical_kline"         # 历史K线
    TICK_DATA = "tick_data"                       # 逐笔成交
    ORDER_BOOK = "order_book"                     # 订单簿/五档行情
    
    # 基本面数据
    FUNDAMENTAL_DATA = "fundamental_data"         # 基本面数据
    FINANCIAL_STATEMENTS = "financial_statements" # 财务报表
    COMPANY_INFO = "company_info"                 # 公司信息
    
    # 市场数据
    MARKET_OVERVIEW = "market_overview"           # 市场概况
    SECTOR_DATA = "sector_data"                   # 板块数据
    INDEX_DATA = "index_data"                     # 指数数据
    
    # 资金流向
    CAPITAL_FLOW = "capital_flow"                 # 资金流向
    MONEY_FLOW = "money_flow"                     # 主力资金
    NORTHBOUND_FLOW = "northbound_flow"           # 北向资金
    
    # 技术指标
    TECHNICAL_INDICATORS = "technical_indicators" # 技术指标
    
    # 新闻和情绪
    NEWS = "news"                                 # 新闻资讯
    NEWS_SENTIMENT = "news_sentiment"             # 新闻情绪
    SOCIAL_SENTIMENT = "social_sentiment"         # 社交媒体情绪
    
    # 特殊数据
    EARNINGS_CALENDAR = "earnings_calendar"       # 财报日历
    DIVIDEND_DATA = "dividend_data"               # 分红数据
    SHAREHOLDER_DATA = "shareholder_data"         # 股东数据
    INSIDER_TRADING = "insider_trading"           # 内部交易
    
    # 衍生品
    OPTIONS_DATA = "options_data"                 # 期权数据
    FUTURES_DATA = "futures_data"                 # 期货数据
    
    # 另类数据
    ALTERNATIVE_DATA = "alternative_data"         # 另类数据


# ==================== 市场能力枚举 ====================

class MarketCapability(str, Enum):
    """
    市场能力枚举
    
    定义适配器支持的市场和交易所。
    """
    
    # 中国市场
    CN_A_SHARES = "cn_a_shares"                   # A股
    CN_B_SHARES = "cn_b_shares"                   # B股
    CN_INDICES = "cn_indices"                     # 中国指数
    CN_FUNDS = "cn_funds"                         # 基金
    CN_BONDS = "cn_bonds"                         # 债券
    
    # 香港市场
    HK_STOCKS = "hk_stocks"                       # 港股
    HK_INDICES = "hk_indices"                     # 香港指数
    
    # 美国市场
    US_STOCKS = "us_stocks"                       # 美股
    US_INDICES = "us_indices"                     # 美国指数
    US_ETF = "us_etf"                             # 美国ETF
    
    # 期货期权
    FUTURES = "futures"                           # 期货
    OPTIONS = "options"                           # 期权
    
    # 外汇
    FOREX = "forex"                               # 外汇
    
    # 数字货币
    CRYPTO = "crypto"                             # 数字货币


# ==================== 性能等级枚举 ====================

class PerformanceLevel(str, Enum):
    """
    性能等级枚举
    
    定义适配器的性能特征。
    """
    
    VERY_HIGH = "very_high"  # 极高性能 (<100ms响应)
    HIGH = "high"            # 高性能 (<500ms响应)
    MEDIUM = "medium"        # 中等性能 (<2s响应)
    LOW = "low"              # 低性能 (<10s响应)
    VERY_LOW = "very_low"    # 极低性能 (>10s响应)


# ==================== 数据新鲜度枚举 ====================

class DataFreshness(str, Enum):
    """
    数据新鲜度枚举
    
    定义数据的实时性程度。
    """
    
    REALTIME = "realtime"          # 实时 (<1s延迟)
    NEAR_REALTIME = "near_realtime" # 准实时 (1-5s延迟)
    DELAYED = "delayed"            # 延时 (15-20分钟延迟)
    END_OF_DAY = "end_of_day"      # 日终 (交易日结束后)
    HISTORICAL = "historical"      # 历史 (T+1及以后)


# ==================== 可靠性等级枚举 ====================

class ReliabilityLevel(str, Enum):
    """
    可靠性等级枚举
    
    定义数据源的可靠性。
    """
    
    VERY_HIGH = "very_high"  # 99.99%以上可用
    HIGH = "high"            # 99.9%以上可用
    MEDIUM = "medium"        # 99%以上可用
    LOW = "low"              # 95%以上可用
    UNKNOWN = "unknown"      # 未知


# ==================== 成本等级枚举 ====================

class CostLevel(str, Enum):
    """
    成本等级枚举
    
    定义使用数据源的成本。
    """
    
    FREE = "free"            # 免费
    LOW = "low"              # 低成本
    MEDIUM = "medium"        # 中等成本
    HIGH = "high"            # 高成本
    VERY_HIGH = "very_high"  # 极高成本


# ==================== 能力声明数据类 ====================

@dataclass
class AdapterCapabilities:
    """
    适配器能力声明
    
    描述一个适配器的完整能力集合。
    
    Attributes:
        data_capabilities: 数据能力集合
        market_capabilities: 市场能力集合
        performance_level: 性能等级
        data_freshness: 数据新鲜度
        reliability_level: 可靠性等级
        cost_level: 成本等级
        rate_limit: 速率限制（请求数/秒）
        supports_streaming: 是否支持流式数据
        supports_batch: 是否支持批量查询
        max_symbols_per_request: 单次请求最大标的数
        notes: 额外说明
    
    示例：
        >>> capabilities = AdapterCapabilities(
        ...     data_capabilities={DataCapability.REALTIME_QUOTES},
        ...     market_capabilities={MarketCapability.CN_A_SHARES},
        ...     performance_level=PerformanceLevel.HIGH
        ... )
    """
    
    # 基础能力
    data_capabilities: Set[DataCapability] = field(default_factory=set)
    market_capabilities: Set[MarketCapability] = field(default_factory=set)
    
    # 性能特征
    performance_level: PerformanceLevel = PerformanceLevel.MEDIUM
    data_freshness: DataFreshness = DataFreshness.DELAYED
    reliability_level: ReliabilityLevel = ReliabilityLevel.MEDIUM
    cost_level: CostLevel = CostLevel.MEDIUM
    
    # 限制
    rate_limit: Optional[float] = None  # 请求数/秒
    max_symbols_per_request: int = 1
    
    # 特性
    supports_streaming: bool = False
    supports_batch: bool = False
    
    # 其他
    notes: str = ""
    metadata: Dict[str, Any] = field(default_factory=dict)
    
    def has_data_capability(self, capability: DataCapability) -> bool:
        """检查是否具有指定的数据能力"""
        return capability in self.data_capabilities
    
    def has_market_capability(self, capability: MarketCapability) -> bool:
        """检查是否支持指定的市场"""
        return capability in self.market_capabilities
    
    def has_all_data_capabilities(self, capabilities: Set[DataCapability]) -> bool:
        """检查是否具有所有指定的数据能力"""
        return capabilities.issubset(self.data_capabilities)
    
    def has_any_data_capability(self, capabilities: Set[DataCapability]) -> bool:
        """检查是否具有任意一个指定的数据能力"""
        return bool(capabilities.intersection(self.data_capabilities))
    
    def has_all_market_capabilities(self, capabilities: Set[MarketCapability]) -> bool:
        """检查是否支持所有指定的市场"""
        return capabilities.issubset(self.market_capabilities)
    
    def has_any_market_capability(self, capabilities: Set[MarketCapability]) -> bool:
        """检查是否支持任意一个指定的市场"""
        return bool(capabilities.intersection(self.market_capabilities))
    
    def get_performance_score(self) -> float:
        """
        获取性能评分 (0-1)
        
        综合考虑性能、新鲜度、可靠性等因素。
        """
        # 性能评分
        perf_scores = {
            PerformanceLevel.VERY_HIGH: 1.0,
            PerformanceLevel.HIGH: 0.8,
            PerformanceLevel.MEDIUM: 0.6,
            PerformanceLevel.LOW: 0.4,
            PerformanceLevel.VERY_LOW: 0.2,
        }
        
        # 新鲜度评分
        fresh_scores = {
            DataFreshness.REALTIME: 1.0,
            DataFreshness.NEAR_REALTIME: 0.9,
            DataFreshness.DELAYED: 0.5,
            DataFreshness.END_OF_DAY: 0.3,
            DataFreshness.HISTORICAL: 0.1,
        }
        
        # 可靠性评分
        reliability_scores = {
            ReliabilityLevel.VERY_HIGH: 1.0,
            ReliabilityLevel.HIGH: 0.8,
            ReliabilityLevel.MEDIUM: 0.6,
            ReliabilityLevel.LOW: 0.4,
            ReliabilityLevel.UNKNOWN: 0.3,
        }
        
        # 加权平均
        score = (
            perf_scores.get(self.performance_level, 0.5) * 0.4 +
            fresh_scores.get(self.data_freshness, 0.5) * 0.3 +
            reliability_scores.get(self.reliability_level, 0.5) * 0.3
        )
        
        return score
    
    def get_cost_score(self) -> float:
        """
        获取成本评分 (0-1，越高越便宜)
        """
        cost_scores = {
            CostLevel.FREE: 1.0,
            CostLevel.LOW: 0.8,
            CostLevel.MEDIUM: 0.5,
            CostLevel.HIGH: 0.3,
            CostLevel.VERY_HIGH: 0.1,
        }
        return cost_scores.get(self.cost_level, 0.5)
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'data_capabilities': [c.value for c in self.data_capabilities],
            'market_capabilities': [c.value for c in self.market_capabilities],
            'performance_level': self.performance_level.value,
            'data_freshness': self.data_freshness.value,
            'reliability_level': self.reliability_level.value,
            'cost_level': self.cost_level.value,
            'rate_limit': self.rate_limit,
            'max_symbols_per_request': self.max_symbols_per_request,
            'supports_streaming': self.supports_streaming,
            'supports_batch': self.supports_batch,
            'notes': self.notes,
            'metadata': self.metadata,
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'AdapterCapabilities':
        """从字典创建"""
        return cls(
            data_capabilities={DataCapability(c) for c in data.get('data_capabilities', [])},
            market_capabilities={MarketCapability(c) for c in data.get('market_capabilities', [])},
            performance_level=PerformanceLevel(data.get('performance_level', 'medium')),
            data_freshness=DataFreshness(data.get('data_freshness', 'delayed')),
            reliability_level=ReliabilityLevel(data.get('reliability_level', 'medium')),
            cost_level=CostLevel(data.get('cost_level', 'medium')),
            rate_limit=data.get('rate_limit'),
            max_symbols_per_request=data.get('max_symbols_per_request', 1),
            supports_streaming=data.get('supports_streaming', False),
            supports_batch=data.get('supports_batch', False),
            notes=data.get('notes', ''),
            metadata=data.get('metadata', {}),
        )


# ==================== 能力匹配辅助函数 ====================

def match_capabilities(
    required: AdapterCapabilities,
    available: AdapterCapabilities
) -> float:
    """
    计算能力匹配度 (0-1)
    
    Args:
        required: 需要的能力
        available: 可用的能力
    
    Returns:
        float: 匹配度分数，1.0表示完全匹配
    
    示例：
        >>> required = AdapterCapabilities(
        ...     data_capabilities={DataCapability.REALTIME_QUOTES}
        ... )
        >>> available = AdapterCapabilities(
        ...     data_capabilities={DataCapability.REALTIME_QUOTES, DataCapability.TICK_DATA}
        ... )
        >>> score = match_capabilities(required, available)
        >>> print(f"匹配度: {score:.2f}")
    """
    scores = []
    
    # 数据能力匹配
    if required.data_capabilities:
        data_match = len(
            required.data_capabilities.intersection(available.data_capabilities)
        ) / len(required.data_capabilities)
        scores.append(data_match * 0.4)  # 40% 权重
    
    # 市场能力匹配
    if required.market_capabilities:
        market_match = len(
            required.market_capabilities.intersection(available.market_capabilities)
        ) / len(required.market_capabilities)
        scores.append(market_match * 0.3)  # 30% 权重
    
    # 性能匹配
    perf_order = [
        PerformanceLevel.VERY_HIGH,
        PerformanceLevel.HIGH,
        PerformanceLevel.MEDIUM,
        PerformanceLevel.LOW,
        PerformanceLevel.VERY_LOW,
    ]
    
    req_perf_idx = perf_order.index(required.performance_level)
    avail_perf_idx = perf_order.index(available.performance_level)
    
    # 如果可用性能 >= 需求性能，得分高
    if avail_perf_idx <= req_perf_idx:
        perf_score = 1.0
    else:
        # 否则根据差距计算分数
        diff = avail_perf_idx - req_perf_idx
        perf_score = max(0, 1.0 - diff * 0.2)
    
    scores.append(perf_score * 0.3)  # 30% 权重
    
    # 如果没有任何要求，返回1.0
    if not scores:
        return 1.0
    
    return sum(scores)


def find_best_adapter(
    required: AdapterCapabilities,
    available_adapters: Dict[str, AdapterCapabilities],
    prefer_performance: bool = True
) -> Optional[str]:
    """
    找到最佳匹配的适配器
    
    Args:
        required: 需要的能力
        available_adapters: 可用适配器字典 {name: capabilities}
        prefer_performance: 是否优先考虑性能
    
    Returns:
        str: 最佳适配器名称，如果没有匹配返回None
    
    示例:
        >>> required = AdapterCapabilities(
        ...     data_capabilities={DataCapability.REALTIME_QUOTES}
        ... )
        >>> adapters = {
        ...     'tushare': tushare_capabilities,
        ...     'akshare': akshare_capabilities,
        ... }
        >>> best = find_best_adapter(required, adapters)
    """
    if not available_adapters:
        return None
    
    scores = {}
    
    for name, capabilities in available_adapters.items():
        match_score = match_capabilities(required, capabilities)
        
        if prefer_performance:
            perf_score = capabilities.get_performance_score()
            # 综合匹配度和性能
            total_score = match_score * 0.7 + perf_score * 0.3
        else:
            total_score = match_score
        
        scores[name] = total_score
    
    # 找到最高分
    if not scores:
        return None
    
    best_adapter = max(scores.items(), key=lambda x: x[1])
    
    # 如果最高分太低（<0.5），返回None
    if best_adapter[1] < 0.5:
        return None
    
    return best_adapter[0]


# ==================== 预定义能力模板 ====================

def create_basic_quote_capabilities() -> AdapterCapabilities:
    """创建基础行情能力模板"""
    return AdapterCapabilities(
        data_capabilities={
            DataCapability.REALTIME_QUOTES,
            DataCapability.HISTORICAL_KLINE,
        },
        market_capabilities={
            MarketCapability.CN_A_SHARES,
        },
        performance_level=PerformanceLevel.MEDIUM,
        data_freshness=DataFreshness.NEAR_REALTIME,
    )


def create_realtime_capabilities() -> AdapterCapabilities:
    """创建实时数据能力模板"""
    return AdapterCapabilities(
        data_capabilities={
            DataCapability.REALTIME_QUOTES,
            DataCapability.TICK_DATA,
            DataCapability.ORDER_BOOK,
        },
        market_capabilities={
            MarketCapability.CN_A_SHARES,
        },
        performance_level=PerformanceLevel.VERY_HIGH,
        data_freshness=DataFreshness.REALTIME,
        supports_streaming=True,
    )


def create_fundamental_capabilities() -> AdapterCapabilities:
    """创建基本面数据能力模板"""
    return AdapterCapabilities(
        data_capabilities={
            DataCapability.FUNDAMENTAL_DATA,
            DataCapability.FINANCIAL_STATEMENTS,
            DataCapability.COMPANY_INFO,
        },
        market_capabilities={
            MarketCapability.CN_A_SHARES,
        },
        performance_level=PerformanceLevel.LOW,
        data_freshness=DataFreshness.END_OF_DAY,
    )

